package com.yonyou.pmclouds.basecom.conf;

import com.alibaba.dubbo.rpc.RpcContext;
import com.yonyou.pmclouds.basecom.multilanguage.Language;
import com.yonyou.pmclouds.basecom.runtime.DevRuntimeEnvironment;
import com.yonyou.pmclouds.basecom.runtime.RpcUtils;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;

/**
 * 开发环境打底数据
 */
//@Profile("dev")
@Configuration
@Slf4j
public class DevDefaultCtxConfiguration implements EnvironmentAware {
    private String enableYHT;

    @Bean
    public FilterRegistrationBean defaultCtxConfiguration() {
        Filter filter = new DevFilter();
        FilterRegistrationBean bean = new FilterRegistrationBean(filter);
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
        bean.setUrlPatterns(Collections.singletonList("/*"));
        return bean;
    }

    @Bean
    @Profile("dev")
    public FilterRegistrationBean dubboRouterFilter() {
        Filter filter = new DubboRouterCtxFilter();
        FilterRegistrationBean bean = new FilterRegistrationBean(filter);
        bean.setOrder(Ordered.LOWEST_PRECEDENCE);
        bean.setUrlPatterns(Collections.singletonList("/*"));
        return bean;

    }

    @Override
    public void setEnvironment(Environment environment) {
        enableYHT = environment.getProperty("yht.enableFilter");
    }

    private static class DubboRouterCtxFilter implements Filter {

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {

        }

        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            try {
                HttpServletRequest req = (HttpServletRequest) servletRequest;
                String dest = req.getHeader("dubbo-dest");
                if (dest != null) {
                    DevRuntimeEnvironment.setDestHost(dest);
                    RpcContext.getContext().setAttachment(DevRuntimeEnvironment.DEV_DEST_KEY, DevRuntimeEnvironment.getDestHost());
                }
            } finally {
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }

        @Override
        public void destroy() {

        }
    }


    private class DevFilter implements Filter {
        private String name;

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            name = filterConfig.getFilterName();
        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            if (!"false".equals(enableYHT)) {
                long startTime = System.currentTimeMillis();
                try {
                    initContext((HttpServletRequest)request);

                    chain.doFilter(request, response);
                } finally {
                    feedTomcatAccessLog(request);
                    log.warn("==========level is {} the method is {}, exe time is {} ", name, ((HttpServletRequest) request).getRequestURI(), System.currentTimeMillis() - startTime);
                }
                return;
            }
            RuntimeEnvironment.setLoginUserId("be0077f7-74bb-4182-be75-e042cddd6c3a");
//            RuntimeEnvironment.setLoginUserId("739de91f-8c97-4cc0-a868-2093a5b42c86");
            // 获取当前数据中心
//            RuntimeEnvironment.setTenantId("botawq9w");
            RuntimeEnvironment.setTenantId("x61tnmfx");
            // 设置语言，目前按照中文处理
            RuntimeEnvironment.setLanguage(Language.SIMPLIFIEDCHINESE);
            //获取系统编码
            RuntimeEnvironment.setSysId("pm_cloud");
            RpcUtils.setRpcContextFromRuntimeEnv();
            chain.doFilter(request, response);
        }

        /**
         * To make tenant / user info available for tomcat access log.
         * @param request
         */
        private void feedTomcatAccessLog(ServletRequest request){
            request.setAttribute("x-tenant-id", RuntimeEnvironment.getTenantId());
            request.setAttribute("x-user-id", RuntimeEnvironment.getLoginUserId());
        }

        /**
         * Context management for several channels to access ygc servers:
         * 1). web.  Refer to YHTWebContextInitFilter.doFilter
         * 2). mobile. Refer to MobileTokenCheckFilter.initMobContext
         * 3). Outter.  Here.
         * 4). Others. //TODO find out pattern.
         * @param request
         */
        private void initContext(HttpServletRequest request){
            //Initialize tenant context for 'outter' apis, no user info available.
            if(request.getServletPath().startsWith("/outter")){
                RuntimeEnvironment.setTenantId(request.getHeader("accountId"));
            }
        }

        @Override
        public void destroy() {

        }
    }
}
